﻿namespace EFS.RC.CC.Tools.Schedulers
{
	/// <summary>
	/// OfficeBusyn
	/// </summary>
	internal class OfficeBusy : EFS.Common.Async.AsyncRoot
	{
		#region Composition

		// conference id 
		private EFS.RC.CC.Tools.Hunters.Agent agentHunter = null;

		// repeat
		private System.Threading.ManualResetEvent officeBusyEvent = null;

		#endregion

		#region Constructor
		
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="agentHunter"></param>
		public OfficeBusy(EFS.RC.CC.Tools.Hunters.Agent agentHunter)
		{
			// set
			EFS.Common.Verify.Reference(agentHunter, "agentHunter");

			// set
			this.agentHunter = agentHunter;

			// register terminated delegate
			this.agentHunter.AsinkTerminatedDelegate.Register(OnAgentHunterTerminated);

			// create new wait event
			officeBusyEvent = new System.Threading.ManualResetEvent(false);

			// log
			EFS.EventLog.Log.LogInfo("OfficeBusy", this);
		}

		#endregion

		#region Usage

		/// <summary>
		/// Describe this object into a nice formated string
		/// </summary>
		/// <returns></returns>
		public override System.String Describe()
		{
			return System.String.Format("EFS.RC.CC.Tools.Schedulers.OfficeBusy [{0}]", agentHunter.Describe());
		}

		/// <summary>
		/// Begin startup
		/// </summary>
		public EFS.Common.Async.AsyncProcess Start()
		{
			// log
			EFS.EventLog.Log.LogInfo("BeginStartup", this);

			// begin
			return BeginAsyncProcess2(StartOfficeBusy, OnExecuteOfficeBusyComplete);
		}

		#endregion

		#region Runtime

		/// <summary>
		/// Unhandled exception
		/// </summary>
		/// <param name="ex"></param>
		protected override void OnException(System.Exception ex)
		{
			// check
			EFS.Common.Verify.Reference(ex, "ex");

			// log
			EFS.EventLog.Log.LogException(ex, this);
		}

		#endregion

		#region Execute

		/// <summary>
		/// ExecuteOfficeBusy
		/// </summary>
		private void StartOfficeBusy()
		{
			// log
			EFS.EventLog.Log.LogInfo("ExecuteOfficeBusy", this);

			// check wait event
			if (!officeBusyEvent.WaitOne(new System.TimeSpan(0, 0, EFS.RC.CC.Config.Settings.BusyAfterSeconds)))
			{
				// shut down
				agentHunter.Busy();
			}
		}

		/// <summary>
		/// Customer service office conference terminated
		/// </summary>
		/// <param name="agentHunter"></param>
		private void OnAgentHunterTerminated(EFS.RC.CC.Tools.Hunters.Agent agentHunter)
		{
			// check
			EFS.Common.Verify.Reference(agentHunter, "agentHunter");

			// check mine
			EFS.Common.Verify.Condition(this.agentHunter.Equals(agentHunter), "Terminated hunter is different");

			// set
			officeBusyEvent.Set();

			// close
			BeginAsyncProcess2(CloseOfficeBusyEvent);
		}

		/// <summary>
		/// Close event
		/// </summary>
		private void CloseOfficeBusyEvent()
		{
			// set event
			officeBusyEvent.Close();
		}

		/// <summary>
		/// ExecuteOfficeBusy complete
		/// </summary>
		/// <param name="ar"></param>
		private void OnExecuteOfficeBusyComplete(EFS.Common.Async.AsyncProcess ap)
		{
			// log
			EFS.EventLog.Log.LogInfo("OnExecuteOfficeBusyComplete", this);

			try
			{
				// check
				ap.Throw();

				// log
				EFS.EventLog.Log.LogInfo("OnExecuteOfficeBusyComplete SUCCCESS", this);
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		#endregion
	}
}
